/*
 * gulp 自动化构建工作流程
 * 1.构建页面实时更新任务。（HTML页面修改、模板页面修改、scss文件更改、图片资源更改、前台JS文件更改）
 * 2.构建SCSS文件实时编译
 * 3。构建文件增量更新
 *
 */
import config from './gulp.config';
let path = require('path');
const gulp = require('gulp'),
    header = require('gulp-header'),
    footer = require('gulp-footer'),
    /**
     * 语法检查
     * @type {[type]}
     */
    jshint = require('gulp-jshint'),
    /**
     * 文件增量编译
     * @type {[type]}
     */
    cached = require('gulp-cached'),
    remember = require('gulp-remember'),
    /**
     * 拥有实时重载（live-reloading）和 CSS 注入的服务器
     * @type {[type]}
     */
    browserSync = require('browser-sync'),
    reload = browserSync.reload,
    filter = require('gulp-filter'),
    /**
     * 编译 SASS
     * @type {[type]}
     */
    sass = require('gulp-sass'),
    sourcemaps = require('gulp-sourcemaps'),
    /**
     * JS 文件压缩
     * @type {[type]}
     */
    uglify = require('gulp-uglifyjs'),
    /**
     * 提示信息
     * @type {[type]}
     */
    notify = require('gulp-notify'),
    /**
     * gulp顺序执行任务
     * @type {[type]}
     */
    gulpSequence = require('gulp-sequence'),
    /**
     * css 压缩
     * @type {[type]}
     */
    minifycss = require('gulp-minify-css'),
    /**
     * 文件合并
     * @type {[type]}
     */
    concat = require('gulp-concat'),

    /**
     * 删除文件和文件夹
     */
    del = require('del'),
    /**
     * 文件md5编译
     * @type {[type]}
     */
    rev = require('gulp-rev'),
    revCollector = require('gulp-rev-collector'),
    stylish = require('jshint-stylish'),
    /**
     * ES6 编译
     * @type {[type]}
     */
    babel = require("gulp-babel"),
    /**
     * 图片精灵
     * @type {[type]}
     */
    spritesmith = require('gulp.spritesmith'),
    /**
     * 图片 base64 转换
     * @type {[type]}
     */
    base64 = require('gulp-base64'),
    /**
     * JS自动化测试
     * @type {[type]}
     */
    mocha = require('gulp-mocha'),
    /**
     * 将 swig 模板静态化
     * @type {[type]}
     */
    swig = require('gulp-swig');

// const ENV = gulp.env;

// if (!!ENV.dev || !!ENV.serverDev) {
//     dist_dir = "./dev/";
// } else if () {
//     dist_dir = "./server-dev/";
// } else {
//     dist_dir = "./dist/";
// }

const url = "http://localhost:" + config.post,
    dist_dir = "./dist/",
    scriptsGlobDone = dist_dir + "./js/",
    css_dir = dist_dir + "./css/",
    views_dir = dist_dir + "./",
    template_dir = dist_dir + "./template/",
    fonts_dir = dist_dir + "./fonts/",
    img_dir = dist_dir + "./img/",
    plugins_dir = dist_dir + "./plugins/";

const src_dir = "./src/",
    scriptsGlob = src_dir + "./js/**/*.js",
    src_scss_dir = src_dir + "./scss/**/*.{sass,scss}",
    src_views_dir = src_dir + "./views/**/*.html",
    src_template_dir = src_dir + "./template/**/*.html",
    src_fonts_dir = src_dir + "./fonts/",
    src_img_dir = src_dir + "./img/",
    src_plugins_dir = src_dir + "./lib/**/*.js";

const routes_dir = "./routes/**/*.js",
    output_routes_dir = "./lib/";

/*
    routes es6 代码实时增量编译
 */
gulp.task('routes_babel', () => {
    return gulp.src(routes_dir)
        .pipe(cached('routes_babel'))
        .pipe(babel({
            presets: ['es2015']
        }))
        .pipe(remember('routes_babel'))
        .pipe(gulp.dest(output_routes_dir));
})

/*
    scripts 代码增量编译
 */

gulp.task('scripts', () => {
    return gulp.src(scriptsGlob)
        .pipe(cached('scripts')) // 只传递更改过的文件
        .pipe(jshint()) // 对这些更改过的文件做一些特殊的处理...
        .pipe(jshint.reporter(stylish)) //高亮提示
        // .pipe(jshint.reporter('fail'))
        .pipe(remember('scripts')) // 把所有的文件放回 stream
});
/**
 * 合并插件
 * @param  {[type]} 'minifyPlugins' [description]
 * @param  {[type]} (               [description]
 * @return {[type]}                 [description]
 */

gulp.task('plugins', () => {
    return gulp.src(src_plugins_dir)
        .pipe(gulp.dest(src_dir + "./plugins/"));
})

/**
 * sass 文件实时自动编译任务
 * @param  {[type]} 'sass' [description]
 * @param  {[type]} (      [description]
 * @return {[type]}        [description]
 */
gulp.task('sass', () => {
    return gulp.src(src_scss_dir)
        .pipe(sass())
        .on('error', (error) => { console.log(error.message) })
        .pipe(gulp.dest(src_dir + "./css/"))
        .pipe(browserSync.reload({ stream: true }))
        .pipe(notify({ message: 'sass:watch task ok' }));
});

/**
 * 图标文件合并
 * @param  {Array}  data) {                           var arr [description]
 * @return {[type]}       [description]
 */
gulp.task('sprite', () => {
    return gulp.src(src_img_dir + './icon/*.png') //需要合并的图片地址
        .pipe(spritesmith({
            imgName: './img/sprite.png', //保存合并后图片的地址
            cssName: './scss/sprite.scss', //保存合并后对于css样式的地址
            padding: 5, //合并时两个图片的间距
            algorithm: 'binary-tree', //注释1
            cssTemplate: function(data) {
                var arr = [];
                data.sprites.forEach(function(sprite) {
                    arr.push(".icon-" + sprite.name +
                        "{" +
                        "background-image: url('" + sprite.escaped_image + "');" +
                        "background-position: " + sprite.px.offset_x + " " + sprite.px.offset_y + ";" +
                        "width:" + sprite.px.width + ";" +
                        "height:" + sprite.px.height + ";" +
                        "}\n");
                });
                return arr.join("");
            }

        }))
        .pipe(gulp.dest(src_dir));
    /* 这里在图片合并完成之后，把图片转为 base64 编码。*/
    // .on('end', () => {
    //     gulp.src(src_dir + "./css/**/*.css").pipe(base64({
    //         baseDir: '',
    //         extensions: ['png'],
    //         maxImageSize: 20 * 1024, // bytes
    //         debug: false
    //     })).pipe(gulp.dest(src_dir+"./css/"))
    // });
});

/**
 * 压缩JS/生成版本号
 * @param  {[type]} ) {'))                 .pipe(footer('}).call(this);'))         .pipe(uglify())        .pipe(rev())        .pipe(gulp.dest(scriptsGlobDone))        .pipe(rev.manifest())        .pipe(gulp.dest(scriptsGlobDone));} [description]
 * @return {[type]}   [description]
 */
gulp.task('minifyjs', () => {
    return gulp.src(scriptsGlob)
        .pipe(header('(function () {')) // 比如 jshinting ^^^
        .pipe(footer('}).call(this);')) // 增加一些类似模块封装的东西
        //.pipe(uglify({
		//	 compress: false, //类型：Boolean 默认：true 是否完全压缩
        //     // preserveComments: 'all' //保留所有注释
        //     preserveComments: false,
          //   mangle: {except: ['require' ,'exports' ,'module' ,'$']},//排除混淆关键字
       // }))
        .pipe(rev())
        .pipe(gulp.dest(scriptsGlobDone))
        .pipe(rev.manifest({ path: 'mf-js.json', merge: true }))
        .pipe(gulp.dest("./manifest/")).on('end', () => {
            /*
                把所有的js、插件里面的图片全部替换成md5编译之后的文件
             */
            gulp.src(['./manifest/mf-img.json', scriptsGlobDone + "/**/*.js"])
                .pipe(revCollector())
                .pipe(gulp.dest(scriptsGlobDone)).on('end', () => {
                    gulp.src(['./manifest/mf-img.json', plugins_dir + "/**/*.js"])
                        .pipe(revCollector())
                        .pipe(gulp.dest(plugins_dir));
                });
        });
});

/**
 * 压缩CSS
 * @param  {[type]} 'minifycss' [description]
 * @param  {[type]} (           [description]
 * @return {[type]}             [description]
 */

gulp.task('minifycss', () => {
    return gulp.src(src_scss_dir)
        .pipe(sass())
        .on('error', (error) => { console.log(error.message) })
        .pipe(minifycss())
        .pipe(rev())
        .pipe(gulp.dest(css_dir))
        .pipe(rev.manifest({ path: 'mf-css.json', merge: true }))
        .pipe(gulp.dest("./manifest/"))
        .pipe(notify({ message: 'minifycss task finished！' }));
});

/**
 * 压缩插件
 * @param  {[type]} 'minifyPlugins' [description]
 * @param  {[type]} (               [description]
 * @return {[type]}                 [description]
 */
gulp.task('minifyPlugins', () => {
    return gulp.src(src_plugins_dir)
        // .pipe(uglify())
        .pipe(rev())
        .pipe(gulp.dest(plugins_dir))
        .pipe(rev.manifest({ path: 'mf-plugins.json', merge: true }))
        .pipe(gulp.dest("./manifest/"));
})


/**
 * 监听文件变更
 * @param  {[type]}   'watcher' [description]
 * @param  {Function} ()        [description]
 * @return {[type]}             [description]
 */
gulp.task('watcher', () => {
    browserSync({
        //不显示在浏览器中的任何通知。
        notify: false,
        //停止自动打开浏览器
        open: true,
        port: config.proxyPost,
        proxy: {
            target: url,
            middleware: (req, res, next) => {
                console.log(req.url);
                next();
            }
        }
    });
    /**
     * 监听图标文件改动
     * @param  {[type]} src_img_dir              +             "./icon/*"    [description]
     * @param  {[type]} ['sprite']).on('change', (event        [description]
     * @return {[type]}                          [description]
     */
    gulp.watch(src_img_dir + "./icon/*", ['sprite']).on('change', (event) => {
        console.log(event);
    });
    /**
     * js文件增量实时编译
     * @type {[type]}
     */
    var watcher = gulp.watch(scriptsGlob, ['scripts', reload]); // 监视与 scripts 任务中同样的文件
    watcher.on('change', (event) => {
        console.log(event);
        if (event.type === 'deleted') { // 如果一个文件被删除了，则将其忘记
            delete cached.caches.scripts[event.path]; // gulp-cached 的删除 api
            remember.forget('scripts', event.path); // gulp-remember 的删除 api
        }
    });
    /**
     * routes ES6 文件增量实时编译
     * @type {[type]}
     */
    gulp.watch(routes_dir, ['routes_babel']).on('change', (event) => {
        console.log(event);
        if (event.type === 'deleted') { // 如果一个文件被删除了，则将其忘记
            delete cached.caches.scripts[event.path]; // gulp-cached 的删除 api
            remember.forget('routes_babel', event.path); // gulp-remember 的删除 api
        }
    });
    /*
        监听sass文件改动
     */
    gulp.watch(src_scss_dir, ['sass', reload]).on('change', (event) => {
        console.log(event);
    });
    /**
     * 监听 视图文件、模板文件、字体文件、图片文件。如果有改动直接刷新页面
     */
    gulp.watch([src_views_dir, src_template_dir, src_fonts_dir], reload).on('change', (event) => {
        console.log(event);
    });
    /*
        监听插件
     */
    gulp.watch(src_plugins_dir, ['plugins', reload]).on('change', (event) => {
        console.log(event);
    });
});
/**
 * dist 文件清除
 * @return {[type]}     [description]
 */
gulp.task('clean:dist', (cb) => {
    return del(['dist/*'], cb);
});
/**
 * lib 文件夹清除
 * @param  {[type]} 'clean:lib' [description]
 * @param  {[type]} (cb         [description]
 * @return {[type]}             [description]
 */
gulp.task('clean:lib', (cb) => {
    return del(['lib/*'], cb);
});

/**
 * 基于文件修改时间，md5 更改文件名称。
 * @param  {[type]} ) {               gulp.src(['./manifest/*.json', src_views_dir])         .pipe(revCollector())         .pipe(gulp.dest(views_dir)); } [description]
 * @return {[type]}   [description]
 */
gulp.task('rev', (cb) => {
    gulpSequence('mf-js&css', 'mf-img')(cb)
});
/**
 * 替换图片文件名称
 * @param  {[type]} 'mf-img' [description]
 * @param  {[type]} (        [description]
 * @return {[type]}          [description]
 */
gulp.task('mf-img', () => {
    gulp.src(['./manifest/mf-img.json', css_dir + "**/*.css"]) //- 读取 rev-manifest.json 文件以及需要进行css名替换的文件
        .pipe(revCollector()) //- 执行文件内css名的替换
        .pipe(gulp.dest(css_dir)); //- 替换后的文件输出的目录
});
/**
 * 替换js文件名称、css文件名称
 * @param  {[type]} 'mf-js' [description]
 * @param  {[type]} (       [description]
 * @return {[type]}         [description]
 */
gulp.task('mf-js&css', () => {
    gulp.src(['./manifest/*.json', src_views_dir]) //- 读取 rev-manifest.json 文件以及需要进行css名替换的文件
        .pipe(revCollector()) //- 执行文件内css名的替换
        .pipe(gulp.dest(views_dir)).on('end', () => {
            gulp.src([views_dir + "/**/*.html", "!/_partial/*.html"]).pipe(swig()).pipe(gulp.dest(views_dir)).on('end', (cb) => {
                del(views_dir + "/_partial/", cb);
            })
        }); //- 替换后的文件输出的目录
});

/**
 * 开发环境 task
 * @param  {[type]} 'dev' [description]
 * @param  {[type]} (cb   [description]
 * @return {[type]}       [description]
 */
gulp.task('dev', (cb) => {
    gulpSequence(['watcher','sass', 'sprite', 'plugins'])(cb)
});


/**
 * 目前字体文件不需要特殊处理，直接复制
 * @param  {[type]} 'copyFonts' [description]
 * @param  {[type]} (cb         [description]
 * @return {[type]}             [description]
 */
gulp.task('copyFonts', (cb) => {
    return gulp.src(src_fonts_dir + "**").pipe(gulp.dest(fonts_dir));
});
/**
 * 图片文件不需要特殊处理，直接复制
 * @param  {[type]} 'copyImg' [description]
 * @param  {[type]} (cb       [description]
 * @return {[type]}           [description]
 */
gulp.task('copyImg', ['sprite'], (cb) => {
    return gulp.src([src_img_dir + "**", "!./src/img/icon/*.png"])
        .pipe(rev())
        .pipe(gulp.dest(img_dir))
        .pipe(rev.manifest({ path: 'mf-img.json', merge: true }))
        .pipe(gulp.dest("./manifest/"))
        .pipe(notify({ message: 'copyImg task finished！' }));;
});

/**
 * 编译代码
 * @param  {[type]} 'build'   [description]
 * @param  {[type]} ['clean'] [description]
 * @param  {[type]} (cb       [description]
 * @return {[type]}           [description]
 */
gulp.task('build', ['clean:dist', 'clean:lib'], (cb) => {
    return gulpSequence(['copyImg', 'minifyjs', 'minifycss', 'minifyPlugins', 'copyFonts'], 'rev')(cb);
});
